feat(exporter): Prisma ORM exporter 추가#151
Open
L33gn21 wants to merge 4 commits into
Open
Conversation
Add Prisma as a fifth ORM backend that converts `TableDef` schemas
into a single `schema.prisma` file (datasource, generator, enums, models).
Why Prisma is wired differently from the other backends:
- Prisma is a single-schema language: datasource (provider, url,
relationMode) and generator (client output) must live in the same
file as the models. Other ORMs only emit model code per file, so
they need no such meta-config. A dedicated `PrismaConfig`
(provider / client_output / relation_mode) is therefore added to
`vespertide-config`.
- The existing export pipeline is N models -> N files (walk_models ->
per-model render -> per-file write -> mod chain). Prisma is N
models -> 1 file with globally-deduplicated enum blocks and a
single datasource/generator header. `cmd_export` short-circuits
with `if matches!(orm, OrmArg::Prisma) { return cmd_export_prisma }`
and assembles the whole schema via `PrismaExporterWithConfig::render_schema`.
Test design (see `prisma/TESTING.md`):
- 3 layers - Layer 1: single-entity rendering (no FK); Layer 2:
schema-aware rendering with relations; Layer 3: edge cases.
- All assertions use `insta::assert_snapshot!` (no `contains` checks)
for precise regression detection.
- `rstest` parameterization for type x nullable matrix, default-value
variants, on_delete/on_update actions, and singularize cases.
- Helpers (`col`, `col_null`, `col_with_default`, `pk`, `uniq`, `idx`,
`fk`, `table`, `render_schema_all`) keep cases compact.
- 65 tests / 54 snapshots cover: column type x nullable (25 types),
PK variants, single/composite unique, single/composite index,
9 default-value forms, enums (string/integer/nullable/default/dedup),
description and column comment, `@@map`, has-many, has-one (unique
FK), nullable FK, multiple FKs to same table, self-reference,
on_delete/on_update (6 actions), composite FK ignored, plural->
singular back-relations, reserved-identifier table/column names,
and special characters in descriptions/defaults.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
owjs3901
requested changes
May 25, 2026
| id Int @id | ||
| val Int @default(dbgenerated("nextval('my_seq')")) | ||
|
|
||
| @@map("items") |
Contributor
There was a problem hiding this comment.
차음부터 model Items로 쓰는 방식을 어떨까요?
Author
There was a problem hiding this comment.
복수형 → 단수형 변환 로직은 제거했습니다.
일반적으로 DB는 snake_case, Prisma는 PascalCase를 사용하는데,
이 부분도 통일해서 @@Map() 사용을 없애는 방향이 좋을까요?
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
개요
5번째 ORM 백엔드로 Prisma를 추가합니다 (기존: SeaORM / SQLAlchemy / SQLModel / JPA).
TableDef스키마를 datasource, generator, enum 블록(전역 dedup), model 블록을포함한 단일
schema.prisma파일로 변환합니다.실행:
vespertide export --orm prisma설계상 특이사항
1. 왜 Prisma만 별도 config (
PrismaConfig)를 가지는가Prisma는 단일 스키마 언어입니다.
datasource db { provider, url, relationMode }와generator client { provider, output }이 모델과 같은 파일 안에 있어야 합니다.나머지 ORM 백엔드(SeaORM / SQLAlchemy / SQLModel / JPA)는 모델 단위 코드만
생성하므로 이런 메타 정보가 필요 없습니다. 즉, Prisma만 "모델 외 입력"(provider,
client output 경로, relation mode)을 받아야 하기 때문에
vespertide-config에PrismaConfig를 새로 추가했습니다. 필드 세 개(provider / client_output /relation_mode)와 postgresql 기본값을 가집니다.
2. 왜
export.rs에if matches!(orm, OrmArg::Prisma) { return cmd_export_prisma(...) }분기가 있는가기존 export 파이프라인은 모델 N개 → 파일 N개 전제입니다:
walk_models→ 모델별render_entity_with_schema→ 파일별 write → mod chain.Prisma는 모델 N개 → 파일 1개이며 위 파이프라인이 만족시킬 수 없는 두 가지
요구가 있습니다:
블록은 파일에 한 번만 등장해야 함)
그래서
cmd_export가 진입 즉시cmd_export_prisma로 분기하고,PrismaExporterWithConfig::render_schema(&all_tables)에서 스키마 전체를 한 번에조립합니다.
Orm::Prisma는 인터페이스 일관성 + 분기 안 자체 clean 호출을 위해clean_export_dir/build_output_path에prisma확장자로 함께 등록만 해두었습니다.
테스트 설계
명세는
crates/vespertide-exporter/src/prisma/TESTING.md에 있습니다. 3-layer 구조:render_entity(table)로 검증.render_entity_with_schema(table, schema)로 검증.TableConstraint::ForeignKey가하나라도 있는
TableDef는 무조건 Layer 2.설계 규칙:
insta::assert_snapshot!사용.assert!(result.contains(...))방식은 금지 — 회귀 감지 정확도 확보 및 출력 전체를 고정.
singularize 등)는
#[rstest]파라미터화로 작성.ColumnDef생성은 로컬 헬퍼(col,col_null,col_with_default,col_with_comment,pk,uniq,idx,fk,table,render_schema_all)로분리하여 케이스 본문을 짧게 유지.
테스트 65개 / 스냅샷 54개가 커버하는 범위:
select,order,model, ...), 예약어 컬럼명 (default,unique, ...), description 안의 newline/quote/brace, default 값 안의 quoteTest plan
cargo build -p vespertide-exporter— 정상cargo test -p vespertide-exporter --lib prisma::— 65 passedcargo test -p vespertide-exporter orm::— 207 passed (Prisma dispatch 스냅샷 포함)examples/app/에cargo run -p vespertide-cli -- export --orm prisma실행해 동작 확인npx prisma format/npx prisma validate통과 여부 확인🤖 Generated with Claude Code